package org.hjl.commonutils.stream;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author hjl
 */
public class StreamUtils {

    public static <T, K> Map<K, List<T>> groupingBy(List<T> in, Function<? super T, ? extends K> classifier) {
        return in.stream()
                .filter(v -> classifier.apply(v) != null)
                .collect(Collectors.groupingBy(classifier));
    }

    public static <T, K, U> Map<K, List<T>> groupingByAndSort(List<T> in, Function<? super T, ? extends K> groupingBy, Function<? super T, ? extends K> sort) {
        return in.stream()
                .filter(v -> groupingBy.apply(v) != null)
                .collect(Collectors.groupingBy(groupingBy));
    }

    public static <T, K> List<K> collect(List<T> in, Function<? super T, ? extends K> classifier) {
        return in.stream()
                .filter(v -> classifier.apply(v) != null)
                .map(classifier)
                .collect(Collectors.toList());
    }

    public static <T, K> Set<K> collectSet(List<T> in, Function<? super T, ? extends K> classifier) {
        return in.stream()
                .filter(v -> classifier.apply(v) != null)
                .map(classifier)
                .collect(Collectors.toSet());
    }

    public static <T, K> List<T> dimensionalityReduction(List<List<T>> in) {
        return in.stream()
                .flatMap(Collection::stream)
                .collect(Collectors.toList());
    }


    public static <T> List<T> distinct(List<T> in) {
        return in.stream().distinct().collect(Collectors.toList());
    }

    public static <T, K> int summary(List<T> in, Function<? super T, ? extends BigDecimal> classifier) {
        return in
                .stream()
                .map(classifier)
                .mapToInt(BigDecimal::intValue).sum();
    }

    /**
     * 对列表某字段求和
     *
     * @param in         列表
     * @param classifier lambda表达式
     */
    public static <T, K> int summaryInteger(List<T> in, Function<? super T, ? extends Integer> classifier) {
        return in
                .stream()
                .map(classifier)
                .mapToInt(Integer::intValue).sum();
    }

    /**
     * 收集到新集合
     */
    public static List<String> collect(List<HashMap<String, String>> pools, String key) {
        return pools.stream()
                .filter(v -> null != v.get(key) && !v.get(key).isEmpty())
                .map(v -> v.get(key)).collect(Collectors.toList());
    }

    public static Map<String, List<HashMap<String, String>>> groupingBy(List<HashMap<String, String>> pools, String key) {
        return pools.stream().collect(Collectors.groupingBy(v -> v.get(key)));
    }
}
